package redis

import (
	"errors"
	"github.com/go-redis/redis"
	"go.uber.org/zap"
	"math"
	"time"
)

const (
	oneWeekInSeconds = 7*24*3600*1000
	scorePerVote = 432	// 超200票加1天
)

var (
	ErrVoteTimeExpire = errors.New("投票已结束")
)

func CreateArticle(articleId int64) error {
	pipeline:=client.TxPipeline()
	pipeline.ZAdd(getRedisKey(KeyArticleTimeZSet), redis.Z{
		Score: float64(time.Now().UnixMilli()),
		Member: articleId,
	})
	pipeline.ZAdd(getRedisKey(KeyArticleScoreZSet), redis.Z{
		Score: float64(time.Now().UnixMilli()),
		Member: articleId,
	})
	_,err:=pipeline.Exec()
	if err!= nil{
		zap.L().Error("redis create article failed", zap.Error(err))
	}
	return err
}

func VoteForArticle(userId, articleId string, val float64) error {
	//1.判断投票限制，是否超过了一周
	articleTime:=client.ZScore(getRedisKey(KeyArticleTimeZSet), articleId).Val()
	if float64(time.Now().UnixMilli())-articleTime> oneWeekInSeconds {
		return ErrVoteTimeExpire
	}
	//2.更新分数
	// 查当前用户给当前帖子的投票纪录
	oval:=client.ZScore(getRedisKey(KeyArticleVotedZSetPrefix+articleId), userId).Val()
	var op float64
	if val>oval {
		op=1
	} else {
		op=-1
	}
	pipeline:=client.TxPipeline()
	diff:=math.Abs(oval-val)	// 计算两次投票的差值
	pipeline.ZIncrBy(getRedisKey(KeyArticleScoreZSet), op*diff*scorePerVote, articleId)
	//3.记录用户为该帖子投过票
	if val==0 {
		pipeline.ZRem(getRedisKey(KeyArticleVotedZSetPrefix+articleId), articleId, userId)
	} else {
		pipeline.ZAdd(getRedisKey(KeyArticleVotedZSetPrefix+articleId), redis.Z{
			Score: val,	//投的赞成票还是反对票
			Member: userId,
		})
	}
	_, err:=pipeline.Exec()
	return err
}
